package com.training.schedule_management_system_admin.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.training.schedule_management_system_admin.constant.Msg;
import com.training.schedule_management_system_admin.entity.*;
import com.training.schedule_management_system_admin.entity.VO.ScheduleVO;
import com.training.schedule_management_system_admin.service.ScheduleServce;
import com.training.schedule_management_system_admin.service.ScheduleframeworkService;
import com.training.schedule_management_system_admin.service.ScheduletableService;
import com.training.schedule_management_system_admin.service.ScheduletemplateService;
import com.training.schedule_management_system_admin.utils.DateListUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Controller
@RequestMapping("/scheduletable")
public class ScheduletableController {

    @Autowired
    ScheduletableService scheduletableService;

    @Autowired
    ScheduleframeworkService scheduleframeworkService;

    @Autowired
    ScheduleServce scheduleServce;

    @Autowired
    ScheduletemplateService scheduletemplateService;

    /*
    获取当前用户下的日程表
     */
    @ResponseBody
    @RequestMapping("/tables")
    public Msg getTables(){
        List<Scheduletable> list = scheduletableService.getAllWithUser();
        return Msg.success().add("tables",list);
    }

    /*
    当前用户下的日程表
    */
    @RequestMapping("/toScheduletable")
    public String toTable(@RequestParam(value = "pageNum",defaultValue ="1") int pageNum,
                          @RequestParam(value = "pageSize",defaultValue = "5") int pageSize,
                          @RequestParam(value = "navigatePages",defaultValue = "5") int navigatePages,
                          Model model){
        JSONObject jsonObject=new JSONObject();
        PageHelper.startPage(pageNum, pageSize);
        List<Scheduletable> tables=scheduletableService.getAllWithUser();
        PageInfo page=new PageInfo(tables,navigatePages);
        jsonObject.put("page",page);
        model.addAttribute("table",new Scheduletable());
        model.addAttribute("msg",jsonObject);
        return "/user/scheduletable";
    }

    /*
    得到日程表
     */
    @ResponseBody
    @RequestMapping("/getScheduletable/{scheduletableId}")
    public Msg getScheduletable(@PathVariable("scheduletableId")Integer scheduletableId){
        Scheduletable table = scheduletableService.getTableById(scheduletableId);
        if (table==null){
            return Msg.fail();
        }
        List<Schedule> schedules = scheduleServce.getAllByTableId(table.getId());
        table.setSchedules(schedules);
        return Msg.success().add("table",table);
    }
    
    /*
    得到日程
     */
    @ResponseBody
    @RequestMapping("/getSchedule/{scheduleId}")
    public Msg getSchedule(@PathVariable("scheduleId")Integer scheduleId){
        Schedule schedule = scheduleServce.getById(scheduleId);
        if(schedule==null){
            return Msg.fail();
        }
        ScheduleVO scheduleVO=new ScheduleVO();
        BeanUtils.copyProperties(schedule,scheduleVO);
        scheduleVO.setId(String.valueOf(schedule.getId()));
        scheduleVO.setDate(DateUtil.format(schedule.getDate(),"yyyy-MM-dd"));
        String time=schedule.getOrderNum()+"("+DateUtil.format(schedule.getCreateTime(),"HH:mm")+"-"+DateUtil.format(schedule.getEndTime(),"HH:mm")+")";
        scheduleVO.setTime(time);
        return Msg.success().add("schedule",scheduleVO);
    }
            

    /*
    日程表的查看(日程表=日程框架和所对应的日程框架项+日程)
    */
    @RequestMapping("/view/{scheduletableId}")
    public String view(@PathVariable("scheduletableId")Integer scheduletableId,Model model){
        JSONObject jsonObject=new JSONObject();
        //得到日程表
        Scheduletable table = scheduletableService.getTableById(scheduletableId);
        if (table==null){
            jsonObject.put("msg","该日程表不存在!");
            model.addAttribute("result",jsonObject);
            return "/user/result";
        }
        jsonObject.put("table",table);

        //得到日程框架
        Scheduleframework framework = scheduleframeworkService.getFrameworkAndTerm(table.getScheduleframeworkId());
        if(framework==null){
            jsonObject.put("msg","该日程框架不存在!");
            model.addAttribute("result",jsonObject);
            return "/user/result";
        }
        jsonObject.put("framework",framework);
        String startDate = DateUtil.format(framework.getStartDate(),"yyyy-MM-dd");
        String endDate = DateUtil.format(framework.getEndDate(),"yyyy-MM-dd");
        List<String> days = DateListUtils.getDays(startDate, endDate);
        jsonObject.put("size",days.size());

        //得到该日程表所有的日程
        List<Schedule> schedules=scheduleServce.getAllByTableId(table.getId());
        if(schedules==null || schedules.isEmpty()){
            model.addAttribute("scheduleVO",new ScheduleVO());
            model.addAttribute("msg",jsonObject);
            return "/user/scheduletable_view";
        }
        jsonObject.put("schedules",schedules);
        model.addAttribute("scheduleVO",new ScheduleVO());
        model.addAttribute("msg",jsonObject);
        return "/user/scheduletable_view";
    }

    /*
    当前日程表所使用的日程框架下的所有日程框架项和所有日程
     */
    @ResponseBody
    @RequestMapping("/view/{scheduletableId}/all")
    public Msg getFrameworkAndTerms(@PathVariable("scheduletableId")Integer scheduletableId){
        Scheduletable table = scheduletableService.getTableById(scheduletableId);
        if(table==null){
            return Msg.fail();
        }
        Scheduleframework framework = scheduleframeworkService.getFrameworkAndTerm(table.getScheduleframeworkId());
        if(framework==null){
            return Msg.fail();
        }
        String startDate = DateUtil.format(framework.getStartDate(),"yyyy-MM-dd");
        String endDate = DateUtil.format(framework.getEndDate(),"yyyy-MM-dd");
        List<String> days = DateListUtils.getDays(startDate, endDate);

        List<String> times =new ArrayList<>();
        for(Scheduleterm term:framework.getScheduleterms()){
            String orderNum = String.valueOf(term.getOrderNum());
            String startTime = DateUtil.format(term.getStartTime(), "HH:mm");
            String endTime = DateUtil.format(term.getEndTime(), "HH:mm");
            String time=orderNum+"("+startTime+"-"+endTime+")";
            times.add(time);
        }

        List<Schedule> schedules = scheduleServce.getAllByTableId(table.getId());
        if(schedules==null || schedules.isEmpty()){
            return Msg.success().add("terms",framework.getScheduleterms()).add("days",days).add("times",times).add("schedules",new ArrayList<>());
        }
        List<ScheduleVO> scheduleVOS=new ArrayList<>();
        for (Schedule schedule:schedules){
            ScheduleVO scheduleVO=new ScheduleVO();
            BeanUtils.copyProperties(schedule,scheduleVO);
            scheduleVO.setId(String.valueOf(schedule.getId()));
            scheduleVO.setDate(DateUtil.format(schedule.getDate(),"yyyy-MM-dd"));
            String time=schedule.getOrderNum()+"("+DateUtil.format(schedule.getCreateTime(),"HH:mm")+"-"+DateUtil.format(schedule.getEndTime(),"HH:mm")+")";
            scheduleVO.setTime(time);
            scheduleVOS.add(scheduleVO);
        }
        return Msg.success().add("terms",framework.getScheduleterms()).add("days",days).add("times",times).add("schedules",scheduleVOS);
    }

    /*
    手工添加日程
     */
    @PostMapping("/view/{scheduletableId}/createSchedule")
    public String createSchedule(@PathVariable("scheduletableId")Integer scheduletableId,
                                 @ModelAttribute("scheduleVO") ScheduleVO scheduleVO,Model model,RedirectAttributes modelMap){
        JSONObject jsonObject=new JSONObject();
        Scheduletable table = scheduletableService.getTableById(scheduletableId);
        if (table==null){
            jsonObject.put("msg","该日程表不存在!");
            model.addAttribute("result",jsonObject);
            return "/user/result";
        }
        String time = scheduleVO.getTime().replace("(", " ").replace("-", " ").replace(")", " ");
        String[] str = time.split(" ");
        scheduleVO.setOrderNum(str[0]);
        scheduleVO.setCreateTime(str[1]);
        scheduleVO.setEndTime(str[2]);

        //判断所要添加的日程有无冲突
        List<Schedule> schedules=scheduleServce.getAllByTableId(table.getId());//先得到该日程表所有的日程
        if(schedules!=null && !schedules.isEmpty()){//表示该日程表不为空，需要判断是否冲突
            for(Schedule schedule:schedules){
                //如果所要添加的日程与原有的日程是同一个日期并且编号也相同，则冲突
                if(scheduleVO.getDate().equals(DateUtil.format(schedule.getDate(),"yyyy-MM-dd")) && scheduleVO.getOrderNum().equals(String.valueOf(schedule.getOrderNum()))){
                    jsonObject.put("result","日程冲突!该时间段已经存在其它日程:"+schedule.getName()+"，不能再添加！");
//                    model.addAttribute("result",jsonObject);
//                    return "/user/result";
                    modelMap.addFlashAttribute("list",jsonObject);
                    return "redirect:/scheduletable/view/"+scheduletableId;
                }
            }
        }
        //无冲突
        Schedule schedule=new Schedule();
        schedule.setScheduletableId(scheduletableId);
        scheduleServce.save(scheduleVO,schedule);
        jsonObject.put("result","添加成功！");
        modelMap.addFlashAttribute("list",jsonObject);
        return "redirect:/scheduletable/view/"+scheduletableId;
    }

    /*
    批量添加日程
     */
    @PostMapping("/view/{scheduletableId}/createScheduleWithTemplate")
    public String createScheduleWithTemplate(@PathVariable("scheduletableId")Integer scheduletableId,
                                             Model model, RedirectAttributes modelMap, String templateId, String startDate, String endDate, String times){
        JSONObject jsonObject=new JSONObject();
        Scheduletable table = scheduletableService.getTableById(scheduletableId);
        if (table==null){
            jsonObject.put("msg","该日程表不存在!");
            model.addAttribute("result",jsonObject);
            return "/user/result";
        }
        Scheduletemplate template = scheduletemplateService.getById(Integer.parseInt(templateId));
        if (template==null){
            jsonObject.put("msg","该日程模版不存在!");
            model.addAttribute("result",jsonObject);
            return "/user/result";
        }
        String time = times.replace("(", " ").replace("-", " ").replace(")", " ");
        String[] str = time.split(" ");
        List<String> days=DateListUtils.getDays(startDate,endDate);

        //判断所要添加的日程有无冲突
        List<String> clash_days=new ArrayList<>();//List集合存储冲突的日期
        List<Schedule> list=scheduleServce.getAllByTableId(table.getId());//先得到该日程表所有的日程
        if(list!=null && !list.isEmpty()){//表示该日程表不为空，需要判断是否冲突
            for (String day:days) {
                for (Schedule schedule : list) {
                    //如果所要添加的日程与原有的日程是同一个日期并且编号也相同，则冲突
                    if (day.equals(DateUtil.format(schedule.getDate(), "yyyy-MM-dd")) && str[0].equals(String.valueOf(schedule.getOrderNum()))) {
                        clash_days.add(day);//将冲突的日期添加到List集合
                    }
                }
            }
        }
        List<Schedule> schedules=new ArrayList<>();
        for (String day:days) {
            if(!clash_days.contains(day)){//排除冲突的日期
                Schedule schedule = new Schedule();
                schedule.setName(template.getName());
                schedule.setPlace(template.getPlace());
                schedule.setComments(template.getComments());
                schedule.setDate(DateUtil.parse(day, "yyyy-MM-dd"));
                schedule.setOrderNum(Integer.parseInt(str[0]));
                schedule.setCreateTime(DateUtil.parse(str[1], "HH:mm"));
                schedule.setEndTime(DateUtil.parse(str[2], "HH:mm"));
                schedule.setScheduletableId(scheduletableId);
                schedules.add(schedule);
            }
        }
        if(schedules.isEmpty()) {
            jsonObject.put("result","添加失败，所选择的日期与时间段全部都与原有日程冲突!");
            modelMap.addFlashAttribute("list",jsonObject);
            return "redirect:/scheduletable/view/"+scheduletableId;
        }
        //批量插入日程
        scheduleServce.saveList(schedules);
        jsonObject.put("result","除了有冲突的日程外，其它的日程都已添加成功!");
        modelMap.addFlashAttribute("list",jsonObject);
        return "redirect:/scheduletable/view/"+scheduletableId;
    }

     /*
    删除日程
     */
     @ResponseBody
     @DeleteMapping("/view/{scheduletableId}/deleteSchedule/{scheduleIds}")
     public Msg deleteSchedule(@PathVariable("scheduletableId")Integer scheduletableId,
                               @PathVariable("scheduleIds")String scheduleIds){
         Scheduletable table = scheduletableService.getTableById(scheduletableId);
         if (table==null){
             return Msg.fail().add("msg","该日程表不存在!");
         }
         if(scheduleIds==null){
             return Msg.fail().add("msg","参数错误!");
         }
         if(scheduleIds.contains("-")){//批量删除
             List<Integer> ids=new ArrayList<>();
             String[] str_ids = scheduleIds.split("-");
             for(String str:str_ids){
                 ids.add(Integer.parseInt(str));
             }
             scheduleServce.deleteBatch(ids);
         }else{//单个删除
             Integer id = Integer.parseInt(scheduleIds);
             scheduleServce.deleteById(id);
         }
         return Msg.success();
     }


    /*
    新增日程表
     */
    @PostMapping("/createTable")
    public String createTable(@ModelAttribute("table")Scheduletable table,Model model){
        JSONObject jsonObject=new JSONObject();
        Scheduleframework framework = scheduleframeworkService.getFrameworkAndTerm(table.getScheduleframeworkId());
        if(framework==null){
            jsonObject.put("msg","该日程框架不存在!");
            model.addAttribute("result",jsonObject);
            return "/user/result";
        }
        scheduletableService.create(table);
        jsonObject.put("msg","保存成功!");
        model.addAttribute("result",jsonObject);
        return "/user/result";
    }

    /*
    修改日程表
     */
    @PostMapping("/updateTable")
    public String updateTable(Model model,String scheduletableId,String name){
        JSONObject jsonObject=new JSONObject();
        Scheduletable table = scheduletableService.getTableById(Integer.parseInt(scheduletableId));
        if (table==null){
            jsonObject.put("msg","该日程表不存在!");
            model.addAttribute("result",jsonObject);
            return "/user/result";
        }
        table.setName(name);
        scheduletableService.update(table);
        jsonObject.put("msg","修改成功!");
        model.addAttribute("result",jsonObject);
        return "/user/result";
    }

    /*
    日程表删除
     */
    @PostMapping("/delete")
    public String delete(String scheduletableId,Model model,HttpSession session){
        JSONObject jsonObject=new JSONObject();
        Scheduletable table = scheduletableService.getTableById(Integer.parseInt(scheduletableId));
        if (table==null){
            jsonObject.put("msg","该日程表不存在!");
            model.addAttribute("result",jsonObject);
            return "/user/result";
        }
        //不能删除其它用户的日程表!
        if(!table.getUserId().equals(((User) session.getAttribute("loginUser")).getId())){
            jsonObject.put("msg", "该日程表不存在!");
            model.addAttribute("result", jsonObject);
            return "/user/result";
        }
        //先删除该日程表上的所有日程
        scheduleServce.delete(table.getId());
        //再删除该日程表
        scheduletableService.delete(table.getId());
        jsonObject.put("msg","删除成功!");
        model.addAttribute("result",jsonObject);
        return "/user/result";
    }

    /*
    日程表查询
     */
    @RequestMapping("/searchTable")
    public String searchTable(@RequestParam(value = "pageNum",defaultValue ="1") int pageNum,
                              @RequestParam(value = "pageSize",defaultValue = "500") int pageSize,
                              @RequestParam(value = "navigatePages",defaultValue = "5") int navigatePages,
                              String value,Model model){
        JSONObject jsonObject=new JSONObject();
        PageHelper.startPage(pageNum, pageSize);
        List<Scheduletable> scheduletables=scheduletableService.findTableLike(value);
        if(scheduletables.isEmpty()){
            jsonObject.put("msg","没有找到包含该名字的日程表");
            model.addAttribute("table_result",jsonObject);
            return "/user/search";
        }
        PageInfo page=new PageInfo(scheduletables,navigatePages);
        jsonObject.put("page",page);
        model.addAttribute("table",new Scheduletable());
        model.addAttribute("msg",jsonObject);
        return "/user/scheduletable";
    }

    /*
    合并日程表
     */
    @ResponseBody
    @PostMapping("/merge")
    public Msg merge(@RequestParam(value = "scheduleList",required = false) String scheduleList, Integer tableId,String name){

//        System.out.println("后端接收的日程"+scheduleList);

        Scheduletable currentTable = scheduletableService.getTableById(tableId);
        Scheduletable table=new Scheduletable();
        table.setName(name);
        table.setScheduleframeworkId(currentTable.getScheduleframeworkId());
        scheduletableService.create(table);

        //先用JSONArray.parseArray将前端传来的String类型转成JSONArray对象
        JSONArray jsonArray = JSONArray.parseArray(scheduleList);
        //再通过JSONObject.parseArray转化为需要的List对象
        List<Schedule> schedules = JSONObject.parseArray(jsonArray.toJSONString(), Schedule.class);
        for(Schedule schedule:schedules){
            schedule.setId(null);
            schedule.setScheduletableId(table.getId());
        }
        scheduleServce.saveList(schedules);

        return Msg.success();
    }

    /*
    两张日程表冲突的日程
     */
    @ResponseBody
    @PostMapping("/clashSchedules")
    public Msg clashSchedules(Integer table1,Integer table2){

        List<Schedule> schedules1 = scheduleServce.getAllByTableId(table1);
        List<Schedule> schedules2 = scheduleServce.getAllByTableId(table2);
        List<List<Schedule>> clashSchedules=new ArrayList<>();
        List<Schedule> schedulesList=new ArrayList<>();
        schedulesList.addAll(schedules1);
        schedulesList.addAll(schedules2);
        List<String> times=new ArrayList<>();

        for(Schedule s1:schedules1){
            for(Schedule s2:schedules2){
                if(s1.getDate().equals(s2.getDate()) && s1.getOrderNum().equals(s2.getOrderNum())){
                    List<Schedule> schedules=new ArrayList<>();
                    schedules.add(s1);
                    schedules.add(s2);
                    clashSchedules.add(schedules);
                    schedulesList.remove(s1);
                    schedulesList.remove(s2);

                    String orderNum = String.valueOf(s1.getOrderNum());
                    String createTime = DateUtil.format(s1.getCreateTime(),"HH:mm");
                    String endTime = DateUtil.format(s1.getEndTime(),"HH:mm");
                    String time=orderNum+"("+createTime+"-"+endTime+")";
                    times.add(time);
                }
            }
        }
//        System.out.println("冲突的日程="+clashSchedules);
        return Msg.success().add("clashSchedules",clashSchedules).add("schedules1",schedules1).add("schedules2",schedules2).add("schedulesList",schedulesList).add("times",times);
    }

    /*
    所选择的日程
     */
    @ResponseBody
    @PostMapping("/chooseSchedules")
    public Msg chooseSchedules(String ids){
        List<Schedule> chooseSchedules=new ArrayList<>();
        String[] str = ids.split("-");
        for(String id:str){
            Schedule schedule = scheduleServce.getById(Integer.parseInt(id));
            chooseSchedules.add(schedule);
        }
        return Msg.success().add("chooseSchedules",chooseSchedules);
    }
}
